package com.jmu.edu.IMApplication.utils;

import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckedTextView;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import com.jmu.edu.IMApplication.MyApplication;
import com.jmu.edu.IMApplication.R;
import com.jmu.edu.IMApplication.fragment.MyFragment;

import java.util.List;

public class ViewUtils {

    //最小滑动距离
    public static final int MIN_FLING_DISTANCE = 50;
    //最小滑动速度
    public static final int MIN_FLING_VELOCITY = 0;
    private static final String TAG = "ViewUtils";


    /**
     * @param layoutInflater 传入调用方的layoutInflater
     * @param tag            要生成的流式布局标签的内容
     * @param index          要生成的标签的序号
     * @param resources      Resources资源，用来获取color
     * @param canChecked     该view是否可以check，并添加默认的点击事件
     * @return 一个包含了checkedTextView（装载标签数据）的view
     */
    public static View getTagItemView(LayoutInflater layoutInflater, String tag, int index, Resources resources, boolean canChecked) {
        View view = layoutInflater.inflate(R.layout.item_tag, null, false);
        CheckedTextView checkedTextView = view.findViewById(R.id.item_tag_name);
        checkedTextView.setText(tag);
        // 设置字体颜色
        checkedTextView.setTextColor(resources.getColor(ColorUtils.getTagFontColor(index)));

        GradientDrawable backgroundDrawable = (GradientDrawable) checkedTextView.getBackground();
        // 设置标签背景色
        backgroundDrawable.setColor(resources.getColor(ColorUtils.getTagBackgroundColor(index)));
        // 初始化设置stroke为5, 颜色为背景色，这是为了和listener的协调 --必须这么设置否则不行，原理暂时未知，推测可能跟drawable的引用有关
        backgroundDrawable.setStroke(5, resources.getColor(ColorUtils.getTagBackgroundColor(index)));


        //如果可以check，那么添加默认的check监听
        if (canChecked) {
            checkedTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (checkedTextView.isChecked()) {
                        // 如果已经被选中，那么取消选中，并取消描边
                        backgroundDrawable.setStroke(5, resources.getColor(ColorUtils.getTagBackgroundColor(index)));
                        checkedTextView.setChecked(false);
                    } else {
                        backgroundDrawable.setStroke(5, checkedTextView.getCurrentTextColor());
                        checkedTextView.setChecked(true);
                    }
                }
            });
        }

        return view;
    }

    /**
     * @param layoutInflater 传入调用方的layoutInflater
     * @param tag            要生成的流式布局标签的内容
     * @param index          要生成的标签的序号
     * @param resources      Resources资源，用来获取color
     * @return 一个包含了checkedTextView（装载标签数据）的view
     */
    public static View getTagItemView(LayoutInflater layoutInflater, String tag, int index, Resources resources) {
        return getTagItemView(layoutInflater, tag, index, resources, false);
    }


    /**
     * 将MyFragment全屏显示，如果已存在则show，不存在则add
     * 使用add的时候由于加载会导致第一次动画无法显示（加载时间完毕后动画没时间了)
     */
    public static void showMyFragment() {
        Fragment fragment = MyApplication.fragmentManager.findFragmentByTag("my");
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.setCustomAnimations(R.anim.from_left, R.anim.out_left);
        if (fragment != null && fragment.isAdded()) {
            transaction.show(fragment);
        } else {
            if (fragment == null) {
                fragment = new MyFragment();
            }
            transaction.add(R.id.main_layout, fragment, "my");
        }
        transaction.commit();
    }

    public static void hideFragment(Fragment hide) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.hide(hide).commit();
    }

    public static void hideFragment(Fragment hide, int enter, int exit) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.setCustomAnimations(enter, exit);
        transaction.hide(hide).commit();
    }

    /**
     * 用来隐藏Fragment的同时，展示一个新的Fragment，可以自己设置出入场动画
     *
     * @param hide  要隐藏的Fragment
     * @param show  要展示的Fragment（不能为null）
     * @param enter 进入动画
     * @param exit  退出动画
     */
    public static void hideFragment(Fragment hide, Fragment show, String tag, int enter, int exit) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.setCustomAnimations(enter, exit);
        // 如果show为null那么就当作没有传入show这个参数
        if (show != null) {
            // 如果要show的Fragment已经存在，那么直接show即可，否则添加
            if (show.isAdded()) {
                Log.d(TAG, "hideFragment: show is added, tag: " + tag);
                transaction.show(show);
            } else {
                Log.d(TAG, "hideFragment: show will be added, tag: " + tag);
                transaction.add(R.id.main_layout, show, tag);
            }
        }
        transaction.hide(hide).commit();
    }

    public static void showFragment(Fragment show, String tag) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.setCustomAnimations(R.anim.from_right, R.anim.out_right);
        if (show != null) {
            // 如果要show的Fragment已经存在，那么直接show即可，否则添加
            if (show.isAdded()) {
                transaction.show(show);
            } else {
                transaction.add(R.id.main_layout, show, tag);
            }
        }
        transaction.commit();
    }

    public static void showFragmentWithoutAnimation(Fragment show, String tag) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        if (show != null) {
            // 如果要show的Fragment已经存在，那么直接show即可，否则添加
            if (show.isAdded()) {
                transaction.show(show);
            } else {
                transaction.add(R.id.main_layout, show, tag);
            }
        }
        transaction.commit();
    }

    public static void showFragment(Fragment show, String tag, int enter, int exit) {
        showFragment(show, tag, enter, exit, false);
    }

    public static void showFragment(Fragment show, String tag, int enter, int exit, boolean isHiddenOthers) {
        FragmentTransaction transaction = MyApplication.fragmentManager.beginTransaction();
        transaction.setCustomAnimations(enter, exit);
        if (show != null) {
            // 如果要show的Fragment已经存在，那么直接show即可，否则添加
            if (show.isAdded()) {
                transaction.show(show);
            } else {
                transaction.add(R.id.main_layout, show, tag);
            }
        }
        if (isHiddenOthers) {
            hideOtherFragments(show, transaction);
        }
        transaction.commit();
    }

    private static void hideOtherFragments(Fragment show, FragmentTransaction transaction) {
        List<Fragment> fragmentList = MyApplication.fragmentManager.getFragments();
        Log.d(TAG, "hideOtherFragments: " + fragmentList.toString());
        for (Fragment fragment : fragmentList) {
            if (!fragment.equals(show) && fragment.isVisible()) {
                if (!MyApplication.getFragmentList().contains(fragment)) {
                    transaction.hide(fragment);
                }

            }
        }
    }

    public static void removeFragment(Fragment remove) {
        View view = remove.getView();
        MyApplication.fragmentManager.beginTransaction()
                .remove(remove)
                .commit();
        unbindDrawables(view);

    }

    private static void unbindDrawables(View view) {
        if (view.getBackground() != null) {
            view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            ((ViewGroup) view).removeAllViews();
        }
    }

    public static void addBackListenerForHide(Fragment fragment) {
        fragment.getView().setFocusableInTouchMode(true);
        fragment.getView().requestFocus();
        fragment.getView().setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
                    ViewUtils.hideFragment(fragment, R.anim.from_right, R.anim.out_right);
                    return true;
                }
                return false;
            }
        });
    }

    /**
     * @param view       要添加回退监听的Fragment的View
     * @param backButton 该Fragment的返回按钮，默认将回退监听和返回按钮的事件绑定
     */
    public static void addBackListenerForHide(View view, Button backButton) {
        view.setFocusableInTouchMode(true);
        view.requestFocus();
        view.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
                    backButton.callOnClick();
                    return true;
                }
                return false;
            }
        });
    }

}
